import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
import java.time.LocalDateTime
import java.util.concurrent.TimeUnit
import kotlin.system.exitProcess

//common-import start
fun adbShell(inCmd: String, deviceSN: String) {
    Run("adb -s $deviceSN shell $inCmd")
}
fun adbShell2(inCmd: String, deviceSN: String) {
    Run(listOf("adb", "-s", deviceSN, "shell", inCmd))
}

fun Run(inCmd: String, inWorkdir: String? = null) {
    Run(inCmd.split(" "), inWorkdir)
}

fun Run(inCmd: List<String>, inWorkdir: String? = null) {
    println("Run: $inCmd")
    val pb: ProcessBuilder = ProcessBuilder(inCmd)
            .directory(File(inWorkdir ?: "."))
            .redirectErrorStream(true)
    val p = pb.start()
    val reader = BufferedReader(InputStreamReader(p.inputStream))
    while (true) {
        val line = reader.readLine() ?: break
        println(line)
    }
    p.waitFor()
    if (0 != p.exitValue()) {
        throw RuntimeException()
    }
}

fun CheckOutput(inCmd: String, inWorkdir: String? = null): List<String> {
    return CheckOutput(inCmd.split(" "), inWorkdir)
}

fun CheckOutput(inCmd: List<String>, inWorkdir: String? = null): List<String> {
    println("Run: $inCmd")
    val ret = mutableListOf<String>()
    val pb: ProcessBuilder = ProcessBuilder(inCmd)
            .directory(File(inWorkdir ?: "."))
            .redirectErrorStream(true)
    val p = pb.start()
    val reader = BufferedReader(InputStreamReader(p.inputStream))
    while (true) {
        val line = reader.readLine() ?: break
        ret.add(line)
    }
    p.waitFor()
    if (0 != p.exitValue()) {
        throw RuntimeException()
    }
    return ret
}

fun isAdbReady(deviceSN: String): Boolean {
    return isDeviceOnline(deviceSN)
}

fun isDeviceOnline(deviceSN: String): Boolean {
    var ret = false
    CheckOutput("adb devices").forEach {
        if (it.contains(deviceSN)) {
            ret = true
        }
    }
    return ret
}

fun isFastbootReady(deviceSN: String): Boolean {
    var ret = false
    CheckOutput("fastboot devices").forEach {
        if (it.contains(deviceSN)) {
            ret = true
        }
    }
    return ret
}

fun waitForAdbReady(deviceSN: String, checkCount: Int = 10, checkInterval: Long = 6) {
    for (i in 0..checkCount) {
        TimeUnit.SECONDS.sleep(checkInterval)
        if (isAdbReady(deviceSN)) {
            println("device $deviceSN adb online")
            break
        } else {
            println("device $deviceSN adb offline, waiting to be ready ...")
        }
    }
}

fun waitForFastbootReady(deviceSN: String, checkCount: Int = 10, checkInterval: Long = 6) {
    for (i in 0..checkCount) {
        TimeUnit.SECONDS.sleep(checkInterval)
        if (isFastbootReady(deviceSN)) {
            println("device $deviceSN fastboot online")
            break
        } else {
            println("device $deviceSN fastboot offline, waiting to be ready ...")
        }
    }
}

fun isDeviceBootComplete(deviceSN: String): Boolean {
    val bootComp = CheckOutput("adb -s $deviceSN shell getprop sys.boot_completed")
    if (bootComp.size == 1 && bootComp[0] == "1") {
        return true
    }
    return false
}

fun enableChatty(deviceSN: String) {
    adbShell("echo N > /sys/module/printk/parameters/console_suspend", deviceSN)
    adbShell("echo 8 > /proc/sys/kernel/printk", deviceSN)
}

fun disableChatty(deviceSN: String) {
    adbShell("echo 4 > /proc/sys/kernel/printk", deviceSN)
}

fun checkDisplayStatus3(): Boolean {
    val ret = CheckOutput("adb shell dumpsys deviceidle").filter { it.contains("mScreenOn") }
    assert(ret.size == 1)
    assert(ret[0].matches(".*=(true|false)".toRegex())) { "Unknown display power status: " + ret[0] }
    if (ret[0].contains("=true")) {
        println("Display ON: ${ret[0]}")
        return true
    }
    if (ret[0].contains("=false")) {
        println("Display OFF: ${ret[0]}")
        return false 
    }
    assert(false)
    return false
}

fun checkDisplayStatus2(): Boolean {
    val ret = CheckOutput("adb shell dumpsys display").filter { it.contains("mScreenState") }
    assert(ret.size == 1)
    assert(ret[0].matches(".*=(ON|OFF)".toRegex())) { "Unknown display power status: " + ret[0] }
    if (ret[0].contains("=ON")) {
        println("Display ON: ${ret[0]}")
        return true
    }
    if (ret[0].contains("=OFF")) {
        println("Display OFF: ${ret[0]}")
        return false 
    }
    assert(false)
    return false
}

fun checkDisplayStatus(): Boolean {
    val ret = CheckOutput("adb shell dumpsys power").filter { it.contains("Display Power") }
    assert(ret.size == 1)
    assert(ret[0].matches(".*(ON|OFF)".toRegex())) { "Unknown display power status: " + ret[0] }
    if (ret[0].contains("=ON")) {
        println("Display ON: ${ret[0]}")
        return true
    }
    if (ret[0].contains("=OFF")) {
        println("Display OFF: ${ret[0]}")
        return false 
    }
    assert(false)
    return false
}

fun envCheck() {
    try {
        assert(true == false)
        println("assert disabled, can not go on")
        exitProcess(1)
    } catch (e: AssertionError) {
        println("assert")
    }
}
//common-import end
